﻿Imports NAudio.Wave
Namespace Audio
	''' <summary>
	''' Used to return a max amplitude and min amplitude for drawing a waveform.
	''' </summary>
	''' <remarks></remarks>
	Public Class SampleAggregator
		Implements ISampleProvider
		' volume
		Public Event MaximumCalculated As EventHandler(Of MaxSampleEventArgs)
		Private maxValue As Single
		Private minValue As Single
		Public Property NotificationCount() As Integer
			Get
				Return m_NotificationCount
			End Get
			Set(value As Integer)
				m_NotificationCount = value
			End Set
		End Property
		Private m_NotificationCount As Integer
		Private count As Integer

		Public ReadOnly Property CurrentCount As Integer
			Get
				Return count
			End Get
		End Property

		Private ReadOnly source As ISampleProvider

		Private ReadOnly channels As Integer

		Public Sub New(source As ISampleProvider)
			channels = source.WaveFormat.Channels
			Me.source = source
		End Sub

		'Private Function IsPowerOfTwo(x As Integer) As Boolean
		'	Return (x And (x - 1)) = 0
		'End Function


		Public Sub Reset()
			count = 0
			maxValue = InlineAssignHelper(minValue, 0)
		End Sub

		Private Sub Add(value As Single)
			maxValue = Math.Max(maxValue, value)
			minValue = Math.Min(minValue, value)
			count += 1
			If count >= NotificationCount AndAlso NotificationCount > 0 Then
				RaiseEvent MaximumCalculated(Me, New MaxSampleEventArgs(minValue, maxValue))
				Reset()
			End If
		End Sub

		Public ReadOnly Property WaveFormat() As WaveFormat Implements ISampleProvider.WaveFormat
			Get
				Return source.WaveFormat
			End Get
		End Property

		Public Function Read(buffer As Single(), offset As Integer, count As Integer) As Integer Implements ISampleProvider.Read
			Dim samplesRead = source.Read(buffer, offset, count)

			Dim n As Integer = 0
			While n < samplesRead
				Add(buffer(n + offset))
				n += channels
			End While
			Return samplesRead
		End Function

		Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
			target = value
			Return value
		End Function
	End Class
End Namespace